package flexibilityDesign;

import java.util.Arrays;
import java.util.List;

import util.Lang;
import ilog.concert.IloNumVar;
import ilog.cplex.IloCplex;

public class TestFlexibilityDesign {
	public static void main(String[] args) {
		// // large numeric experiments
		// int[] products = { 4, 5, 5, 8, 10 };
		// int[] plants = { 4, 5, 7, 8, 10 };
		// int[] groups = { 50, 50, 50, 80, 80 };
		// int M = 2000;
		double lcpm = 5;
		//
		// for (int i = 0; i < products.length; i++) {
		// int n = products[i];
		// int m = plants[i];
		//
		// Support.generateLinkCost(n, m, 150, 300);
		// Support.generateProfitMargin(n, m, 150, 300, lcpm);
		// Support.generateCapacities(n, m);
		//
		// for (int ins = 0; ins < 10; ins++) {
		// Support.generateDemands_normal(M, n, 100, 900, 50, 150, ins);
		//
		// hybridCut(n, m, M, ins, groups[i]);
		//
		// // MIP solve
		// DesignMIP dm = new DesignMIP(n, m, M, lcpm);
		// dm.MIPSolve();
		//
		// // single cut
		// TestSingleCut tsc = new TestSingleCut(n, m, M);
		// tsc.setSimulationIndex(ins);
		// tsc.setEnhance(true, false, false, true);
		// tsc.Lshape();
		// }
		// }

		int n = 6;// product number
		int m = 6;// plant number
		int M = 2000;
		// int[] ns = { 9, 10 };
		// int[] ms = { 9, 10 };
		//
		// for (int i = 0; i < ns.length; i++) {
		// n = ns[i];
		// m = ms[i];

		Support.generateDemands_normal(M, n, 100, 900, 50, 150);
		Support.generateLinkCost(n, m, 150, 300);
		Support.generateProfitMargin(n, m, 150, 300, lcpm);
		Support.generateCapacities(n, m);
		Support.generateCapacityCost(m, 150 / 2, 300 / 2, lcpm);
		//
		// // mixed cut version
		// // mixedCut(n, m, M, lcpm);
		hybridCut(n, m, M, 0, 50);
		//
		// hybridCut_cap(n, m, M);

		// DesignMIPCapInvest mipCap = new DesignMIPCapInvest(n, m, M, lcpm);
		// mipCap.MIPSolve();
		// }
		// System.out.println("@finish");

		// single cut test
		// StructureDesign design = new StructureDesign(n, m, M, lcpm);
		// design.Lshaped();
		// TestSingleCut tsc = new TestSingleCut(n, m, M);
		// tsc.setEnhance(true, false, false, true);
		// tsc.Lshape();

		// int[] ns = { 8 };
		// multi-cut test
		// for (int nv : ns) {
		// StructureDesignMultiCut design_multi = new StructureDesignMultiCut(n,
		// m, M, lcpm);
		// design_multi.Lshaped();
		// }

		// chaining(m, M, ns);

		// MIP solve
		// DesignMIP dm = new DesignMIP(n, m, M, lcpm);
		// dm.MIPSolve();

		// testMIP();

		// multicut(n, m, M);
	}

	private static void hybridCut_cap(int n, int m, int M) {
		StructureDesignHybridCutCapInvest cal = new StructureDesignHybridCutCapInvest(n, m, M, 50);
		cal.setEnhances(true, false, false, true, false, false);
		cal.Lshape();
	}

	private static void multicut(int n, int m, int M) {
		TestMulticut tmc = new TestMulticut(n, m, M, true);
		tmc.Lshape();
		// tmc.detectCriticalS();
	}

	private static void hybridCut(int n, int m, int M, int index, int groups) {
		StructureDesignHybridCut cal = new StructureDesignHybridCut(n, m, M, groups);
		cal.setSimulationIndex(index);

		// // HC
		// cal.setEnhances(false, false, false, false, false, false);
		// cal.Lshape();
		//
		// // HC-PC
		// cal.setEnhances(true, false, false, false, false, false);
		// cal.Lshape();
		//
		// // HC-PC-TR
		// cal.setEnhances(true, false, true, false, false, false);
		// cal.Lshape();
		//
		// // HC-AM
		// cal.setEnhances(false, false, false, true, false, false);
		// cal.Lshape();
		//
		// // HC-PC-AM
		// cal.setEnhances(true, false, false, true, false, false);
		// cal.Lshape();
		//
		// // HC-PC-TR-AM
		// cal.setEnhances(true, false, true, true, false, false);
		// cal.Lshape();
		//
		// // HC-WS
		// cal.setEnhances(false, false, false, false, true, false);
		// cal.Lshape();
		//
		// // HC-WS-MA
		cal.setEnhances(false, false, false, true, true, false);
		cal.Lshape();

		// HC-PC-SC
		// cal.setEnhances(true, false, false, true, false, true);
		// cal.Lshape();
	}

	private static void chaining(int m, int M, int[] ns) {
		for (int nv : ns) {
			// Support.generateDemands_normal(M, nv, 100, 900, 50, 150);
			// Support.generateLinkCost(nv, m, 150, 300);
			// Support.generateProfitMargin(nv, m, 150, 300, lcpm);
			// Support.generateCapacities(nv, m);

			ChainingDesign cd = new ChainingDesign(nv, m, M);
			double value = cd.calculateCost();
			System.out.println("@instance m/n = " + m + "/" + nv + ", M = " + M + ", value = " + value);
		}
	}

	private static void testMIP() {
		try {
			IloCplex cplex = new IloCplex();
			IloNumVar[] x = cplex.boolVarArray(3);
			int[] c = { 3, -2, 5 };
			cplex.addMaximize(cplex.scalProd(c, x));

			cplex.addLe(cplex.sum(x[0], cplex.prod(2, x[1]), cplex.prod(-1, x[2])), 2);
			cplex.addLe(cplex.sum(x[0], cplex.prod(4, x[1]), x[2]), 4);
			cplex.addLe(cplex.sum(x[0], x[1]), 3);
			cplex.addLe(cplex.sum(cplex.prod(4, x[1]), x[2]), 6);

			// double[] init = { 0, 1, 0 };
			// cplex.addMIPStart(x, init);

			long start = System.currentTimeMillis();

			if (cplex.solve()) {
				System.out.println("time=" + (System.currentTimeMillis() - start));
				System.out.println("objVal = " + cplex.getObjValue());
				System.out.println(Arrays.toString(cplex.getValues(x)));
			}
			cplex.end();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
